#include<iostream>
#include<unistd.h>
#include<pthread.h>
#include<string>

//下面的代码有一个致命的错误，就是我在创建类来传递对象的时候，每调用指针，所以在每次给它传递变量的时候，都属于一个新的锁，因为临时对象的存在，所以此时每个锁都是崭新的，所以每一次都是一个新的锁，完成不了他的实名





int ticket1 = 1000; //代表有1k张票

// pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;//全局锁
class Mutex
{
public:
    Mutex(pthread_mutex_t* lock,const char* name)   //直接传引用，嘎嘎好用
    :_lock(lock), 
    _name(name)
    {}
    pthread_mutex_t* _lock;
    std :: string _name;
};
void* ticket(void* agrc)
{
    Mutex* slef = static_cast<Mutex*>(agrc);
    while(1)
    {
        pthread_mutex_lock(slef->_lock);  //线程一进来先锁住，让只能自己访问这部分代码,位置放错了，应该吧他放到循环的开头，已进入循环就上锁
        if(ticket1  > 0)
        {
            usleep(1000);
            printf("%s 抢到了票 , 票数：%d\n",slef->_name.c_str(),ticket1--);
            pthread_mutex_unlock(slef->_lock);  //访问完就解锁
        }
        else
        {
            //此时票没了，它的存在已经没有了意义
            pthread_mutex_unlock(slef->_lock);  //访问完就解锁
            break;
        }
    }
    return nullptr;
}



int main()
{
    pthread_t tid1,tid2,tid3,tid4;
    pthread_mutex_t lock; //先创建好一个锁的变量
    pthread_mutex_init(&lock,nullptr);  //初始化锁
    Mutex* id1 = new Mutex(&lock,"thread-1");
    Mutex* id2 = new Mutex(&lock,"thread-2");
    Mutex* id3 = new Mutex(&lock,"thread-3");
    Mutex* id4 = new Mutex(&lock,"thread-4");   //先把锁的类创立好，再进行线程的调度，不然会出bug,隔了一天把自己否定了，所以我的这个理论是不正确的，这样出不了bug
    pthread_create(&tid1,nullptr,ticket,id1);
    pthread_create(&tid2,nullptr,ticket,id2);
    pthread_create(&tid3,nullptr,ticket,id3);
    pthread_create(&tid4,nullptr,ticket,id4);
    //一个一个的进行线程等待
    pthread_join(tid1,nullptr);
    pthread_join(tid2,nullptr);
    pthread_join(tid3,nullptr);
    pthread_join(tid4,nullptr);
    //全局的锁不用自己释放，局部的需要自己释放
    delete id1,id2,id3,id4;
    pthread_mutex_destroy(&lock);
    return 0;
}












// int ticket1 = 1000; //代表有1k张票

// // pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;//全局锁
// class Mutex
// {
// public:
//     Mutex(pthread_mutex_t lock,const char* name)
//     :_lock(lock),
//     _name(name)
//     {}
//     pthread_mutex_t _lock;
//     std :: string _name;
// };
// void* ticket(void* agrc)
// {
//     Mutex* slef = static_cast<Mutex*>(agrc);
//     while(1)
//     {
//         if(ticket1  > 0)
//         {
//             pthread_mutex_lock(&slef->_lock);  //线程一进来先锁住，让只能自己访问这部分代码
//             usleep(1000);
//             printf("%s 抢到了票 , 票数：%d\n",slef->_name.c_str(),ticket1--);
//             pthread_mutex_unlock(&slef->_lock);  //访问完就解锁
//         }
//         else
//         {
//             //此时票没了，它的存在已经没有了意义
//             pthread_mutex_unlock(&slef->_lock);  //访问完就解锁
//             break;
//         }
//     }
//     return nullptr;
// }



// int main()
// {
//     pthread_t tid;
//     pthread_mutex_t lock; //先创建好一个锁的变量
//     pthread_mutex_init(&lock,nullptr);  //初始化锁
//     Mutex* id1 = new Mutex(lock,"thread-1");
//     pthread_create(&tid,nullptr,ticket,id1);
//     Mutex* id2 = new Mutex(lock,"thread-2");
//     pthread_create(&tid,nullptr,ticket,id2);
//     Mutex* id3 = new Mutex(lock,"thread-3");
//     pthread_create(&tid,nullptr,ticket,id3);
//     Mutex* id4 = new Mutex(lock,"thread-4");
//     pthread_create(&tid,nullptr,ticket,id4);
//     //一个一个的进行线程等待
//     pthread_join(tid,nullptr);
//     pthread_join(tid,nullptr);
//     pthread_join(tid,nullptr);
//     pthread_join(tid,nullptr);
//     //全局的锁不用自己释放，局部的需要自己释放
//     pthread_mutex_destroy(&lock);
//     return 0;
// }